package com.sogoodsoft.web.common;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperPrintManager;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.export.JRXlsExporter;
import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
import net.sf.jasperreports.engine.util.JRLoader;

import org.apache.commons.dbcp.BasicDataSource;
import org.springside.modules.utils.web.struts2.Struts2Utils;

import com.sogoodsoft.util.InfoSpringUtil;
import com.sogoodsoft.util.InfosysUtils;
import com.sogoodsoft.web.WebConstants;

/**
 * 
 * Report FormBean，用于定义报表的属性，传递到前台按属性进行展示
 * 公司名称，报表里用 $P{rootName}参数获得就行了
 * @author xiaozu
 *
 */
public class Report {
	
	/**下载另存文件名，不带扩展名**/
	public String storeName="报表";
	
	/**报表/WEB-INF/report/目录下，编译好的.jasper文件名**/
	public String jasper;
	
	/**是否打印，默认false**/
	public boolean print = false;
	
	/**报表参数**/
	@SuppressWarnings("rawtypes")
    public Map para = new HashMap();
	
	/**报表导出类型 Report.EXT，即导出文件扩展名pdf,excel,rtf等**/
	public EXT ext = EXT.pdf;
	
	
	private JasperReport jReport;
	private JasperPrint jPrint;
	private BasicDataSource dataSource;
	private ServletOutputStream out;
	private HttpServletResponse response ;
	private HttpServletRequest request ;
	private static String rootName ;//组织结构根节点名称，报表里使用参数rootName获得
	/**
	 *报表类型枚举
	 */
	public enum EXT{
		pdf("application/pdf"),excel("application/vnd.ms-excel"),rtf("application/rtf");
		private String type;
		private EXT(String type){
			this.type = type;
		}
		public String getType() {
			return type;
		}
		
		/**
		 * 比较两个类型是否相同
		 * @param e
		 * @return
		 */
		public boolean equals(EXT e){
			return e.getType().equals(type);
		}
		
	}
	
	
	/**
	 * 将ID转换BigDecimal，存入para,KEY="ID"
	 * @param id
	 */
	@SuppressWarnings("unchecked")
	public void putID(Long id){
		para.put("ID", new BigDecimal(id));
	}
	
	/**
	 * 将ID转换BigDecimal，存入para,指定KEY
	 * @param id
	 */
	@SuppressWarnings("unchecked")
	public void putID(String key,Long id){
		para.put(key, new BigDecimal(id));
	}
	
	/**
	 * 根据jasperName，返回jasper的完整路径
	 * @return jasper的完整路径
	 */
	public String jasperPath(){
		return InfosysUtils.translatePath(WebConstants.REPORT_PATH+File.separator+jasper);
	}
	
	/**
	 * 
	 * @return 下载另存文件全名
	 * @throws UnsupportedEncodingException 
	 */
	public String storeAs() throws UnsupportedEncodingException{
		String name = "";
		if(ext.equals(EXT.pdf)){
			name = storeName+".pdf";
		}
		else if(ext.equals(EXT.excel)){
			name =  storeName+".xls";
		}
		else if(ext.equals(EXT.rtf)){
			name = storeName+".rtf";
		}
		return URLEncoder.encode(name,"UTF-8");
	}

	/**
	 * 使用JDBC数据源
	 * 按report属性生成报表，必须在action中使用，因为需要用reuqest和response
	 * @return
	 * @throws IOException
	 * @throws JRException 
	 */
	@SuppressWarnings("unchecked")
    public String make() throws Exception{
		response = Struts2Utils.getResponse();
		request = Struts2Utils.getRequest();
		if(rootName==null){
			rootName = InfosysUtils.getOrgRoot(request);
		}
		para.put("rootName", rootName);
		
		jReport = (JasperReport)JRLoader.loadObjectFromFile(jasperPath());
		dataSource = (BasicDataSource)InfoSpringUtil.getBean(request,"dataSource");
		jPrint = JasperFillManager.fillReport(jReport,para,dataSource.getConnection());
		if(print){
			JasperPrintManager.printReport(jPrint,true);
		}else{
			if(ext.equals(EXT.pdf)){
				makepdf();
			}else if(ext.equals(EXT.excel)){
				makeExcel();
			}else if(ext.equals(EXT.rtf)){
				
			}
		}
		return null;
	}
	
	/**
	 * 使用JRDataSource数据源
	 * 按report属性生成报表，必须在action中使用，因为需要用reuqest和response
	 * @return
	 * @throws IOException
	 * @throws JRException 
	 */
	public String make(ListJRDataSource jrsource)throws Exception{
		response = Struts2Utils.getResponse();
		request = Struts2Utils.getRequest();
		if(rootName==null){
			rootName = InfosysUtils.getOrgRoot(request);
		}
		para.put("rootName", rootName);
		
		jReport = (JasperReport)JRLoader.loadObjectFromFile(jasperPath());
		dataSource = (BasicDataSource)InfoSpringUtil.getBean(request,"dataSource");
		jPrint = JasperFillManager.fillReport(jReport,para,jrsource);
		if(print){
			JasperPrintManager.printReport(jPrint,true);
		}else{
			if(ext.equals(EXT.pdf)){
				makepdf();
			}else if(ext.equals(EXT.excel)){
				makeExcel();
			}else if(ext.equals(EXT.rtf)){
				
			}
		}
		
		return null;
	}
	
	protected void genReport(){
		
	}
	
	protected void makepdf() throws JRException, IOException{		
			response.setContentType(ext.getType());
			response.setCharacterEncoding("UTF-8");
			response.setHeader("Content-Disposition", "attachment; filename=\""+storeAs());
			out = response.getOutputStream();
			JasperExportManager.exportReportToPdfStream(jPrint, out);
			out.flush();
	}
	
	protected void makeExcel() throws JRException, IOException{
		response.setContentType(ext.getType());
		response.setCharacterEncoding("UTF-8");
		response.setHeader("Content-Disposition", "attachment; filename=\""+storeAs());
		out = response.getOutputStream();
		JRXlsExporter exporter = new JRXlsExporter();  
        exporter.setParameter(JRExporterParameter.JASPER_PRINT, jPrint);  
        exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, out); 
        exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET,Boolean.FALSE);// 删除多余的ColumnHeader
        exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND,Boolean.FALSE);// 显示边框
        exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS,Boolean.TRUE); // 删
        exporter.exportReport();// 导出  
        out.flush();// 关闭流  	
	}
	
	/**
	 * 使用时请自行扩充
	 */
	protected void makeRtf(){}
}
